home *** CD-ROM | disk | FTP | other *** search
- /*
- HEADER: CUG nnn.nn;
- TITLE: YACC - Yet Another Compilier-Compilier
- VERSION: 1.0 for IBM-PC
- DATE: JAN 28, 1985
- DESCRIPTION: LALR(1) Parser Generator. From UNIX
- KEYWORDS: Parser Generator Compilier-Compilier YACC
- SYSTEM: IBM-PC and Compatiables
- FILENAME: YYPARS.C
- WARNINGS: This program is not for the casual user. It will
- be useful primarily to expert developers.
- CRC: N/A
- SEE-ALSO: LEX and PREP
- AUTHORS: Scott Guthery 11100 leafwood lane Austin, TX 78750
- COMPILERS: DESMET-C
- REFERENCES: UNIX Systems Manuals
- Adapted for the Mac 90/04/13 and after, Maarten Meijer
- */
- # ifndef YYMAXDEPTH
- # define YYMAXDEPTH 150
- # endif
-
- /* # define __UNION__ */ /* allow UNION asignment */
-
- # define YYFLAG (-1000)
- # define YYERROR goto yyerrlab
- # define YYACCEPT return(0)
- # define YYABORT return(1)
-
- #define YYWAS0ERR 0
- #define YYWAS1ERR 1
- #define YYWAS2ERR 2
- #define YYWAS3ERR 3
-
- #ifdef THINK_C
- void yyinit(void); /* prototype to be called at startup */
- #endif
-
- /* parser for yacc output */
-
- # ifdef YYDEBUG
- int yydebug = 0; /* 1 for debugging */
- # endif
-
- static YYSTYPE *yyv = NULL; /* [YYMAXDEPTH]; /* where the values are stored */
- static int yychar = -1; /* current input token number */
- static int yynerrs = 0; /* number of errors */
- static short yyerrflag = 0; /* error recovery flag */
- static short *yys = NULL; /* [YYMAXDEPTH]; */
-
- yyparse()
- {
-
- /* short yys[YYMAXDEPTH]; */ /* allocate instead to reduce stack usage */
- short yyj, yym;
- register YYSTYPE *yypvt;
- register short yystate, *yyps, yyn;
- register YYSTYPE *yypv;
- register short *yyxi;
- if(yyv == NULL) {
- yyv = (YYSTYPE *) calloc (YYMAXDEPTH, sizeof(YYSTYPE));
- if(yyv == NULL)
- {
- yyerror( "yacc no space for yyv[] vector" );
- return(1);
- }
- }
- if(yys == NULL) {
- yys = (short *) calloc (YYMAXDEPTH, sizeof(short));
- if(yys == NULL)
- {
- yyerror( "yacc no space for yys[] vector" );
- return(1);
- }
- }
- #ifdef YACC_RESOURCES
- yyinit();
- #endif
- yystate = 0;
- yychar = -1;
- yynerrs = 0;
- yyerrflag = 0;
- yyps= &yys[-1];
- yypv= &yyv[-1];
-
- yystack: /* put a state and value onto the stack */
-
- # ifdef YYDEBUG
- if( yydebug ) {
- if( ! ((yystate == 0) && (yychar == -1)))
- printf( "state %d, next token %d == '%c'\n",
- yystate,
- yychar,
- isprint(yychar) ? yychar : '◊');
- }
- # endif
- if( ++yyps> &yys[YYMAXDEPTH] )
- {
- yyerror( "yacc stack overflow" );
- return(1);
- }
- *yyps = yystate;
- ++yypv;
- # ifdef __UNION__
- yyunion(yypv, &yyval);
- # else
- *yypv = yyval;
- # endif
- yynewstate:
-
- yyn = yypact[yystate];
-
- if( yyn<= YYFLAG )
- goto yydefault; /* simple state */
-
- if( yychar<0 )
- if( (yychar=yylex())<0 )
- yychar=0;
- if( (yyn += yychar)<0 || yyn >= YYLAST )
- goto yydefault;
-
- if( yychk[ yyn=yyact[ yyn ] ] == yychar )
- {
- /* valid shift */
- yychar = -1;
- # ifdef __UNION__
- yyunion(&yyval, &yylval);
- # else
- yyval = yylval;
- # endif
- yystate = yyn;
- if( yyerrflag > 0 )
- --yyerrflag;
- goto yystack;
- }
- yydefault:
- /* default state action */
-
- if( (yyn=yydef[yystate]) == -2 )
- {
- if( yychar<0 )
- if( (yychar=yylex())<0 )
- yychar = 0;
- /* look through exception table */
- for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 )
- ; /* VOID */
-
- for(yyxi+=2; *yyxi >= 0; yyxi+=2)
- {
- if( *yyxi == yychar )
- break;
- }
- if( (yyn = yyxi[1]) < 0 )
- return(0); /* accept */
- }
-
- if( yyn == 0 )
- {
- /* error */
- /* error ... attempt to resume parsing */
-
- switch( yyerrflag )
- {
-
- case YYWAS0ERR: /* brand new error */
-
- yyerror( "syntax error" );
- yyerrlab:
- ++yynerrs;
- case YYWAS1ERR:
- case YYWAS2ERR: /* incompletely recovered error ... try again */
-
- yyerrflag = 3;
-
- /* find a state where "error" is a legal shift action */
-
- while ( yyps >= yys )
- {
- yyn = yypact[*yyps] + YYERRCODE;
- if( yyn>= 0 && yyn < YYLAST &&
- yychk[yyact[yyn]] == YYERRCODE )
- {
- yystate = yyact[yyn]; /* simulate a shift of "error" */
- goto yystack;
- }
- yyn = yypact[*yyps];
-
- /* the current yyps has no shift onn "error", pop stack */
-
- # ifdef YYDEBUG
- if( yydebug )
- printf( "error: pops state %d, recover state %d\n",
- *yyps,
- yyps[-1] );
- # endif
- --yyps;
- --yypv;
- }
-
- /* there is no state on the stack with an error shift ... abort */
-
- yyabort:
- return(1);
-
-
- case YYWAS3ERR: /* no shift yet; clobber input char */
-
- # ifdef YYDEBUG
- if( yydebug )
- printf( "error: discards token %d\n", yychar );
- # endif
-
- if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */
- yychar = -1;
- goto yynewstate; /* try again in the same state */
-
- }
-
- }
-
- /* reduction by production yyn */
-
- # ifdef YYDEBUG
- if( yydebug ) printf("reduce with rule %d\n",yyn);
- # endif
- yyps -= yyr2[yyn];
- yypvt = yypv;
- yypv -= yyr2[yyn];
- # ifdef __UNION__
- yyunion(&yyval, &yypv[1]);
- # else
- yyval = yypv[1];
- # endif
- yym=yyn;
- /* consult goto table to find next state */
- yyn = yyr1[yyn];
- yyj = yypgo[yyn] + *yyps + 1;
- if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn )
- yystate = yyact[yypgo[yyn]];
- switch(yym)
- {
- $A
- }
- goto yystack; /* stack new state and value */
- }
-
- #ifdef THINK_C
- #ifdef YACC_RESOURCES
- /*
- * Use this to set up the parser tables from resources instead of the
- * global space (precious at 32K max size). MM 90/04/16
- */
-
- static setup_yacc_res(short **tab, char *pname);
-
- static setup_yacc_res(short **tab, char *pname) {
- short **h;
- /*
- * Not that using Get1NamedResource will produce errors when debugging
- * with THINK C, since the project resource file is opened after the
- * project itself, but I consider this a safer call. MM 90/04/16
- */
- h = (short **)Get1NamedResource(YACC_RESTYPE, pname);
- if(h == NULL)
- Debugger();
- /*
- * to move them out of the way, another possibility is to allocate
- * a pointer and copy the information wuith a BlockMove();
- */
- DetachResource(h);
- MoveHHi(h);
- HLock(h);
- HNoPurge(h);
- /* set up the pointer */
- *tab = *h;
- }
- #endif
-
- /* This function is called by llinit() in LEXLIB, to initialize
- * yylval to zero, and also by yyparse() if using resources for
- * the tables.
- */
- void yyinit() {
- int i, j;
- char *p;
- #ifdef YACC_RESOURCES
- short saveResFile, saveVol;
- #ifndef YACC_ALONE
- short yResFile;
- #endif
- #endif
-
- /* set yylval to zero */
- i = sizeof(YYSTYPE);
- for(j = i, p = (char *)&yylval; j; j--, p++)
- *p = '\0';
-
- /* initialize the tables */
- #ifdef YACC_RESOURCES
- if(yydef == 0L) { /* check only one */
- /* save the state of things */
- GetVol(0L, &saveVol);
- saveResFile = CurResFile();
- #ifdef YACC_ALONE
- /* UseResFile(CurApRefNum); /* will not work when debugging */
- /* with THINK C, since the project */
- /* resource file is opened after */
- /* the project itself. Better to */
- /* uncomment this when doing the */
- /* final build. MM 90/04/16 */
- #else
- yResFile = OpenResFile(YACC_RESFILENAME);
- UseResFile(yResFile);
- #endif
- setup_yacc_res(&yyact, "\pyyact");
- setup_yacc_res(&yypact, "\pyypact");
- setup_yacc_res(&yypgo, "\pyypgo");
- setup_yacc_res(&yyr1, "\pyyr1");
- setup_yacc_res(&yyr2, "\pyyr2");
- setup_yacc_res(&yychk, "\pyychk");
- setup_yacc_res(&yydef, "\pyydef");
- #ifndef YACC_ALONE
- CloseResFile(yResFile);
- #endif
- /* restore the state of things */
- UseResFile(saveResFile);
- SetVol(0L, saveVol);
- }
- #endif
- }
- #endif
-